/*-+-*****************************************************************************
 Copyright (C) 2009-2012 Oceanside Software Corporation (R)
 Dallas, Texas

 Author       : Jason T. Brower
 Purpose      : This file is part of a point-of-sale software package
                originally written for Table-Service Restaurants.
              
 Date         : July 8th of 2012
              
 History      : The application that this software file belongs to was 
                written over a 3-Year period.  The first version was written
                in C# .Net 3.5 using Windows Forms.  Being new to .Net at
                the time, I soon learned of Windows Presentation Foundation,
                liked the graphics capabilities and databinding so I
                migrated to WPF.  When the .Net 4.0 framework was released
                the application was migrated from 3.5 to 4.0. Now today,
                .Net 4.5 RC is out and I was already in process of migrating
                before I made this public.
                
Excuse Me     : Please excuse the coding style, it is not representative of
                my typical work.  During the three years I was under a very
                tight budget, constantly running out of funding and was 
                working 18 hour days hyped up on 5-Hour Energy.  The 
                design is not textbook.  It is monolythic because of
                previous issues I will not get into.  There are few comments
                in the code and the ones that are there may be incorrect.
                
What it is not: This is not the exact version that I took through PA-DSS 2.0
                nor is it the exact version running at my customer sites.
                I removed some details for security purposes including some
                encryption algorithms.  The reporting was removed because
                I was including a third party library that cannot be 
                published with this Open Source.
                
What it is    : This application has been running at high volume restaraunts
                for over a year.  It never freezes, crashes or does anything
                unexpected.  So long as it is built, installed and configured
                correctly, it is a strong system that we can all enhance.

Contact       : Please note that I can no longer work for free.  However, you
                can reach me at information@oceansidesw.com.                                                      

*********************************************************************************/
using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

#if _LOCALDB
  using Oceanside.LocalDB;
#else
using Oceanside.RemoteDB;
#endif
namespace Oceanside
{
    /// <summary>
    /// Interaction logic for PageLogin.xaml
    /// </summary>
    public partial class PageUserImp : PageImpBaseClass
    {
        static string _origBohPassword = "";

        /// <summary>
        /// Needed to populate the login type drop down.
        /// </summary>
        List<String> listLoginType = new List<String>();

        /// <summary>
        /// Surely nobody has more than 30 children for tax purposes?
        /// </summary>
        const int CONST_MAX_DEPENDANTS = 30;

        const int CONST_MIN_BOH_PASSWORD_LEN = 7;

        DbLinkedTextBox tbaddress1TextBox;
        DbLinkedTextBox tbaddress2TextBox;
        DbLinkedTextBox tbstateTextBox;
        DbLinkedTextBox tbbohPasswordTextBox;
        DbLinkedTextBox tbcityTextBox;
        DbLinkedTextBox tbfirstNameTextBox;
        DbLinkedTextBox tblastNameTextBox;
        DbLinkedTextBox tbmiddleNameTextBox;
        DbLinkedTextBox tbssnTextBox;
        DbLinkedTextBox tbtelephoneTextBox;
        DbLinkedTextBox tbtextboxKeypadPassword;
        DbLinkedTextBox tbuserNameTextBox;
        DbLinkedTextBox tbzipcodeTextBox;
        ComboBox comboBoxName;
        DbLinkedRadioButton sexCheckBoxFemale;
        DbLinkedRadioButton sexCheckBoxMale;
        DbLinkedCheckBox checkBoxFoh;
        DbLinkedCheckBox checkBoxBoh;
        DbLinkedTextBox tbStartDate;
        DbLinkedTextBox tbBirthdate;


        /// <summary>
        /// Constructor
        /// </summary>
        public PageUserImp(UIElementCollection userInfoGridChild, DbLinkedTextBox tbaddress1TextBox, DbLinkedTextBox tbaddress2TextBox, DbLinkedTextBox tbstateTextBox, DbLinkedTextBox tbbohPasswordTextBox, DbLinkedTextBox tbcityTextBox, DbLinkedTextBox tbfirstNameTextBox, DbLinkedTextBox tblastNameTextBox, DbLinkedTextBox tbmiddleNameTextBox, DbLinkedTextBox tbssnTextBox, DbLinkedTextBox tbtelephoneTextBox, DbLinkedTextBox tbtextboxKeypadPassword, DbLinkedTextBox tbuserNameTextBox, DbLinkedTextBox tbzipcodeTextBox, ComboBox comboBoxName,
            DbLinkedRadioButton sexCheckBoxFemale, DbLinkedRadioButton sexCheckBoxMale, DbLinkedCheckBox checkBoxFoh, DbLinkedCheckBox checkBoxBoh, DbLinkedTextBox tbExternalPayrollId, DbLinkedTextBox tbCountry, DbLinkedTextBox tbemail, DbLinkedTextBox tbMobilePhone,
            DbLinkedTextBox tbStartDate,
        DbLinkedTextBox tbBirthdate, Button bSetStartDate, Button bSetBirthdate, GroupBox mainGroup)
        {
            this.ButtonNumber = "4";
            this.ButtonLabelText = "Users";

            mNewGroupIsDisabled = true;
            mDeleteGroupIsDisabled = true;
            mButtonNewEntityName = "New User";
            mButtonDeleteEntityName = "Terminate User";
            RegisterSaveMeGroupBoxes(null, mainGroup);

            this.tbaddress1TextBox = tbaddress1TextBox;
            this.tbaddress2TextBox = tbaddress2TextBox;
            this.tbstateTextBox = tbstateTextBox;
            this.tbbohPasswordTextBox = tbbohPasswordTextBox;
            this.tbcityTextBox = tbcityTextBox;
            this.tbfirstNameTextBox = tbfirstNameTextBox;
            this.tblastNameTextBox = tblastNameTextBox;
            this.tbmiddleNameTextBox = tbmiddleNameTextBox;
            this.tbssnTextBox = tbssnTextBox;
            this.tbtelephoneTextBox = tbtelephoneTextBox;
            this.tbtextboxKeypadPassword = tbtextboxKeypadPassword;
            this.tbuserNameTextBox = tbuserNameTextBox;
            this.tbzipcodeTextBox = tbzipcodeTextBox;
            this.comboBoxName = comboBoxName;
            this.sexCheckBoxFemale = sexCheckBoxFemale;
            this.sexCheckBoxMale = sexCheckBoxMale;
            this.checkBoxFoh = checkBoxFoh;
            this.checkBoxBoh = checkBoxBoh;
            this.tbStartDate = tbStartDate;
            this.tbBirthdate = tbBirthdate;

            bSetStartDate.Click += new RoutedEventHandler(bSetStartDate_Click);
            bSetBirthdate.Click += new RoutedEventHandler(bSetBirthdate_Click);

            mListOfControlsToDisableInNonEditMode.Add(bSetBirthdate);
            mListOfControlsToDisableInNonEditMode.Add(bSetStartDate);

            ///Register the controls and lock the form.
            RegisterUiElementsList(userInfoGridChild);
            UpdateControlsState(FORM_MODES_ENUM.LOCKED, null, null);

            ///Add all text boxes to the list.
            mTextBoxesList.Add(tbCountry);
            mTextBoxesList.Add(tbemail);
            mTextBoxesList.Add(tbMobilePhone);
            mTextBoxesList.Add(tbStartDate);
            mTextBoxesList.Add(tbBirthdate);
            mTextBoxesList.Add(tbExternalPayrollId);
            mTextBoxesList.Add(tbCountry);
            mTextBoxesList.Add(tbaddress1TextBox);
            mTextBoxesList.Add(tbaddress2TextBox);
            mTextBoxesList.Add(tbstateTextBox);
            mTextBoxesList.Add(tbbohPasswordTextBox);
            mTextBoxesList.Add(tbcityTextBox);
            mTextBoxesList.Add(tbfirstNameTextBox);
            mTextBoxesList.Add(tblastNameTextBox);
            mTextBoxesList.Add(tbmiddleNameTextBox);
            mTextBoxesList.Add(tbssnTextBox);
            mTextBoxesList.Add(tbtelephoneTextBox);
            mTextBoxesList.Add(tbtextboxKeypadPassword);
            mTextBoxesList.Add(tbuserNameTextBox);
            mTextBoxesList.Add(tbzipcodeTextBox);

            ///Add the comboboxes.
            ListofComboboxes.Add(comboBoxName);

            ///Register for the events.
            sexCheckBoxFemale.Click += new RoutedEventHandler(sexCheckBoxFemale_Click_NOTHROW);
            sexCheckBoxMale.Click += new RoutedEventHandler(sexCheckBoxMale_Click_NOTHROW);

            ///Attach event handlers to all the boh login checkbox and the foh keypad login checkbox types so we can either enable
            ///or disable the password box associated with each one.
            checkBoxFoh.Checked += new RoutedEventHandler(checkBoxKeypad_Checked_NOTHROW);
            checkBoxFoh.Unchecked += new RoutedEventHandler(checkBoxKeypad_Unchecked_NOTHROW);
            checkBoxBoh.Checked += new RoutedEventHandler(checkBoxBoh_Checked_NOTHROW);
            checkBoxBoh.Unchecked += new RoutedEventHandler(checkBoxBoh_Unchecked_NOTHROW);

            ///If the selection changes lock the form down.
            comboBoxName.SelectionChanged += new SelectionChangedEventHandler(comboBoxName_SelectionChanged_NOTHROW);

            mEntityAddDeleteLoggingEnabled = true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void bSetBirthdate_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                USER selected = comboBoxName.SelectedItem as USER;
                if (selected != null)
                {
                    DateTimePicker dtp = new DateTimePicker(false, false, false, false, false, "Please Select the Employee's Birthdate");
                    dtp.ShowDialog();
                    if (DateTimePicker.LastResponse == UserResponse.YES)
                    {
                        selected.Birthdate = DateTimePicker.LastStartSelectedDateTime;
                        Context.SaveChanges();
                    }
                }
            }
            catch (Exception exc)
            {
                Constants.ErrorDispatcher.Notify(Error.EType.E_PLACEHOLDER, exc);
            }
        }

        void bSetStartDate_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                USER selected = comboBoxName.SelectedItem as USER;
                if (selected != null)
                {
                    DateTimePicker dtp = new DateTimePicker(false, false, false, false, false, "Please Select the Employee's Hired Date");
                    dtp.ShowDialog();
                    if (DateTimePicker.LastResponse == UserResponse.YES)
                    {
                        selected.HiredDate = DateTimePicker.LastStartSelectedDateTime;
                        Context.SaveChanges();
                    }
                }
            }
            catch (Exception exc)
            {
                Constants.ErrorDispatcher.Notify(Error.EType.E_PLACEHOLDER, exc);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        override public List<EntityObject> GetEntityObjectSet()
        {
            return new List<EntityObject>(Context.USERS.ToList());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void comboBoxName_SelectionChanged_NOTHROW(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                USER selectedUser = (sender as ComboBox).SelectedItem as USER;

                if (null != selectedUser)
                {
                    _origBohPassword = Sec.DecryptBytes(selectedUser.LoginBohPassword);
                }
            }
            catch (System.Exception exc)
            {
                Constants.ErrorDispatcher.Notify(Error.EType.E_PAGEUSER_CBNAME_SEL_CHANGED, exc);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void textBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
            if (sender is TextBox)
            {
                (sender as TextBox).SelectAll();
            }
        }

        public static bool StringIsNumeric(string str, Boolean skipDecimalPoint = true)
        {
            foreach (char c in str)
            {
                if (skipDecimalPoint)
                {
                    if (!Char.IsNumber(c) && (c != '.')) return false;
                }
                else
                {
                    if (!Char.IsNumber(c)) return false;
                }
            }

            return true;
        }

        private static void AddTrainingTimeClock(DominicaEntities context)
        {
            try
            {
                USER trainingUser = context.USERS.Where(u => u.LoginKeyPassword != null && u.LoginKeyPassword.Equals("3333") && u.IsTerminated == false).FirstOrDefault();
                if (trainingUser == null)
                {
                    trainingUser = new USER();
                    trainingUser.FirstName = "Training";
                    trainingUser.LastName = "Timeclock";
                    trainingUser.UserName = "traintimeclock";
                    trainingUser.ScreenName = "Training Timeclock";
                    trainingUser.IsTraining = true;
                    trainingUser.HiredDate = DateTime.Now;
                    trainingUser.Birthdate = DateTime.Now;
                    trainingUser.LoginKeyPassword = "3333";
                    context.USERS.AddObject(trainingUser);
                    context.SaveChanges();
                }

                if (trainingUser.ROLES.Count == 0 || !trainingUser.ROLES.Where(r => r.Name != null && r.Name.Equals("Training Timeclock") && r.IsDeleted == false).Any())
                {
                    ACCESS_LEVEL trainingLevel = context.ACCESS_LEVELS.Where(a => a.Name != null && a.Name.Equals("Training Timeclock") && a.IsDeleted == false).FirstOrDefault();
                    if (trainingLevel == null)
                    {
                        trainingLevel = new ACCESS_LEVEL();
                        trainingLevel.Name = "Training Timeclock";
                        trainingLevel.CanOrder = false;
                        context.ACCESS_LEVELS.AddObject(trainingLevel);
                        context.SaveChanges();
                    }

                    JOB_CODE trainingJobCode = context.JOB_CODES.Where(a => a.Name != null && a.Name.Equals("Training Timeclock") && a.IsDeleted == false).FirstOrDefault();
                    if (trainingJobCode == null)
                    {
                        trainingJobCode = new JOB_CODE();
                        trainingJobCode.Name = "Training Timeclock";
                        trainingJobCode.IsManager = false;
                        context.JOB_CODES.AddObject(trainingJobCode);
                        context.SaveChanges();
                    }

                    PAYGRADE trainingPayGrade = context.PAYGRADES.Where(a => a.Name != null && a.Name.Equals("Training Timeclock") && a.IsDeleted == false).FirstOrDefault();
                    if (trainingPayGrade == null)
                    {
                        trainingPayGrade = new PAYGRADE();
                        trainingPayGrade.Name = "Training Timeclock";
                        trainingPayGrade.IsSalaried = false;
                        trainingPayGrade.WageRate = 6.50M;
                        trainingPayGrade.IsEligibleForOvertimePay = false;
                        context.PAYGRADES.AddObject(trainingPayGrade);
                        context.SaveChanges();
                    }

                    ROLE role = new ROLE();
                    role.Name = "Training Timeclock";
                    role.JOB_CODE = trainingJobCode;
                    role.PAYGRADE = trainingPayGrade;
                    role.ACCESS_LEVEL = trainingLevel;
                    context.ROLES.AddObject(role);
                    role.UserId = trainingUser.Id;
                    trainingUser.ROLES.Add(role);
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                Logging.LogException(ex);
            }
        }

        private static void AddTrainingServer(DominicaEntities context)
        {
            try
            {
                USER trainingUser = context.USERS.Where(u => u.LoginKeyPassword != null && u.LoginKeyPassword.Equals("2222") && u.IsTerminated == false).FirstOrDefault();
                if (trainingUser == null)
                {
                    trainingUser = new USER();
                    trainingUser.FirstName = "Training";
                    trainingUser.LastName = "Server";
                    trainingUser.UserName = "trainserver";
                    trainingUser.ScreenName = "Training Server";
                    trainingUser.IsTraining = true;
                    trainingUser.HiredDate = DateTime.Now;
                    trainingUser.Birthdate = DateTime.Now;
                    trainingUser.LoginKeyPassword = "2222";
                    context.USERS.AddObject(trainingUser);
                    context.SaveChanges();
                }

                if (trainingUser.ROLES.Count == 0 || !trainingUser.ROLES.Where(r => r.Name != null && r.Name.Equals("Training Server") && r.IsDeleted == false).Any())
                {
                    ACCESS_LEVEL trainingLevel = context.ACCESS_LEVELS.Where(a => a.Name != null && a.Name.Equals("Training Server") && a.IsDeleted == false).FirstOrDefault();
                    if (trainingLevel == null)
                    {
                        trainingLevel = new ACCESS_LEVEL();
                        trainingLevel.Name = "Training Server";
                        trainingLevel.CanOrder = true;
                        context.ACCESS_LEVELS.AddObject(trainingLevel);
                        context.SaveChanges();
                    }

                    JOB_CODE trainingJobCode = context.JOB_CODES.Where(a => a.Name != null && a.Name.Equals("Training Server") && a.IsDeleted == false).FirstOrDefault();
                    if (trainingJobCode == null)
                    {
                        trainingJobCode = new JOB_CODE();
                        trainingJobCode.Name = "Training Server";
                        trainingJobCode.IsManager = false;
                        context.JOB_CODES.AddObject(trainingJobCode);
                        context.SaveChanges();
                    }

                    PAYGRADE trainingPayGrade = context.PAYGRADES.Where(a => a.Name != null && a.Name.Equals("Training Server") && a.IsDeleted == false).FirstOrDefault();
                    if (trainingPayGrade == null)
                    {
                        trainingPayGrade = new PAYGRADE();
                        trainingPayGrade.Name = "Training Server";
                        trainingPayGrade.IsSalaried = false;
                        trainingPayGrade.WageRate = 6.50M;
                        trainingPayGrade.IsEligibleForOvertimePay = false;
                        context.PAYGRADES.AddObject(trainingPayGrade);
                        context.SaveChanges();
                    }

                    ROLE role = new ROLE();
                    role.Name = "Training Server";
                    role.JOB_CODE = trainingJobCode;
                    role.PAYGRADE = trainingPayGrade;
                    role.ACCESS_LEVEL = trainingLevel;
                    context.ROLES.AddObject(role);
                    role.UserId = trainingUser.Id;
                    trainingUser.ROLES.Add(role);
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                Logging.LogException(ex);
            }
        }

        private static void AddTrainingManager(DominicaEntities context)
        {
            try
            {
                USER trainingUser = context.USERS.Where(u => u.LoginKeyPassword != null && u.LoginKeyPassword.Equals("1111") && u.IsTerminated == false).FirstOrDefault();
                if (trainingUser == null)
                {
                    trainingUser = new USER();
                    trainingUser.FirstName = "Training";
                    trainingUser.LastName = "Manager";
                    trainingUser.UserName = "trainmanager";
                    trainingUser.ScreenName = "Training Manager";
                    trainingUser.IsTraining = true;
                    trainingUser.HiredDate = DateTime.Now;
                    trainingUser.Birthdate = DateTime.Now;
                    trainingUser.LoginKeyPassword = "1111";
                    context.USERS.AddObject(trainingUser);
                    context.SaveChanges();
                }

                if (trainingUser.ROLES.Count == 0 || !trainingUser.ROLES.Where(r => r.Name != null && r.Name.Equals("Training Manager") && r.IsDeleted == false).Any())
                {
                    ACCESS_LEVEL trainingLevel = context.ACCESS_LEVELS.Where(a => a.Name != null && a.Name.Equals("Training Manager") && a.IsDeleted == false).FirstOrDefault();
                    if (trainingLevel == null)
                    {
                        trainingLevel = new ACCESS_LEVEL();
                        trainingLevel.Name = "Training Manager";
                        context.ACCESS_LEVELS.AddObject(trainingLevel);
                        context.SaveChanges();
                    }

                    JOB_CODE trainingJobCode = context.JOB_CODES.Where(a => a.Name != null && a.Name.Equals("Training Manager") && a.IsDeleted == false).FirstOrDefault();
                    if (trainingJobCode == null)
                    {
                        trainingJobCode = new JOB_CODE();
                        trainingJobCode.Name = "Training Manager";
                        trainingJobCode.IsManager = true;
                        context.JOB_CODES.AddObject(trainingJobCode);
                        context.SaveChanges();
                    }

                    PAYGRADE trainingPayGrade = context.PAYGRADES.Where(a => a.Name != null && a.Name.Equals("Training Manager") && a.IsDeleted == false).FirstOrDefault();
                    if (trainingPayGrade == null)
                    {
                        trainingPayGrade = new PAYGRADE();
                        trainingPayGrade.Name = "Training Manager";
                        trainingPayGrade.IsSalaried = false;
                        trainingPayGrade.WageRate = 6.50M;
                        trainingPayGrade.IsEligibleForOvertimePay = false;
                        context.PAYGRADES.AddObject(trainingPayGrade);
                        context.SaveChanges();
                    }

                    ROLE role = new ROLE();
                    role.Name = "Training Manager";
                    role.JOB_CODE = trainingJobCode;
                    role.PAYGRADE = trainingPayGrade;
                    role.ACCESS_LEVEL = trainingLevel;
                    context.ROLES.AddObject(role);
                    role.UserId = trainingUser.Id;
                    trainingUser.ROLES.Add(role);
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                Logging.LogException(ex);
            }
        }
        public override void EditStarted()
        {
            bool wasInTraining = Constants.IsTrainingMode;
            try
            {
                ///Make sure that the trainer exists in the database
                AddTrainingManager(SHIFT.GlobalContext);
                AddTrainingServer(SHIFT.GlobalContext);
                AddTrainingTimeClock(SHIFT.GlobalContext);
                Constants.IsTrainingMode = true;
                using (DominicaEntities context = new DominicaEntities(DominicaEntities.GetEfConString()))
                {
                    AddTrainingManager(context);
                    AddTrainingServer(context);
                    AddTrainingTimeClock(context);
                }
            }
            catch (Exception ex)
            {
                Logging.LogException(ex);
            }
            finally
            {
                Constants.IsTrainingMode = wasInTraining;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public override bool SaveMe()
        {
            checkBoxBoh.IsChecked = false;
            checkBoxFoh.IsChecked = false;
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void checkBoxBoh_Unchecked_NOTHROW(object sender, RoutedEventArgs e)
        {
            try
            {
                tbbohPasswordTextBox.Visibility = System.Windows.Visibility.Hidden;
            }
            catch (System.Exception exc)
            {
                Constants.ErrorDispatcher.Notify(Error.EType.E_PAGEUSER_CB_BOH_UNCHECKED, exc);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void checkBoxBoh_Checked_NOTHROW(object sender, RoutedEventArgs e)
        {
            try
            {
                tbbohPasswordTextBox.Visibility = System.Windows.Visibility.Visible;
            }
            catch (System.Exception exc)
            {
                Constants.ErrorDispatcher.Notify(Error.EType.E_PAGEUSER_CB_BOH_CHECKED, exc);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void checkBoxKeypad_Unchecked_NOTHROW(object sender, RoutedEventArgs e)
        {
            try
            {
                tbtextboxKeypadPassword.Visibility = System.Windows.Visibility.Hidden;
            }
            catch (System.Exception exc)
            {
                Constants.ErrorDispatcher.Notify(Error.EType.E_PAGEUSER_CB_KEYPAD_UNCHECKED, exc);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void checkBoxKeypad_Checked_NOTHROW(object sender, RoutedEventArgs e)
        {
            try
            {
                tbtextboxKeypadPassword.Visibility = System.Windows.Visibility.Visible;
            }
            catch (System.Exception exc)
            {
                Constants.ErrorDispatcher.Notify(Error.EType.E_PAGEUSER_CB_KEYPAD_CHECKED, exc);
            }
        }

        /// <summary>
        /// Make the change button visible if clicked and all values are valid.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void sexCheckBoxMale_Click_NOTHROW(object sender, RoutedEventArgs e)
        {
            try
            {
                ///Binding is not working for the radio buttons which actually bind to integers so they can have three states.
                ///Male, Female and not set.
                USER selectedUser = (USER)comboBoxName.SelectedItem;
                if (selectedUser != null)
                {
                    selectedUser.Sex = SetSexInteger();
                }
            }
            catch (System.Exception exc)
            {
                Constants.ErrorDispatcher.Notify(Error.EType.E_PAGEUSER_MALE_CLICK, exc);
            }
        }

        /// <summary>
        /// Make the change button visible if clicked and all values are valid.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void sexCheckBoxFemale_Click_NOTHROW(object sender, RoutedEventArgs e)
        {
            try
            {
                ///Binding is not working for the radio buttons which actually bind to integers so they can have three states.
                ///Male, Female and not set.
                USER selectedUser = (USER)comboBoxName.SelectedItem;

                if (selectedUser != null)
                {
                    selectedUser.Sex = SetSexInteger();
                }
            }
            catch (System.Exception exc)
            {
                Constants.ErrorDispatcher.Notify(Error.EType.E_PAGEUSER_FEMALE_CLICK, exc);
            }
        }

        /// <summary>
        /// Convert the select sex to the correct DB short value.
        /// </summary>
        /// <param name="radio"></param>
        /// <returns></returns>
        private short SetSexInteger()
        {
            if (sexCheckBoxMale.IsChecked.Value)
                return 1;
            else if (sexCheckBoxFemale.IsChecked.Value)
                return 2;
            else
                return 0;
        }


        /// <summary>
        /// Determine if the username that they are trying to use is actually available.
        /// </summary>
        /// <returns></returns>
        private bool UsernameIsAvailable()
        {
            Boolean usernameIsAvailable = false;

            ///Create the query object.
            USER selectedUser = (USER)comboBoxName.SelectedItem;
            var query = from USER in Context.USERS where (USER.UserName == tbuserNameTextBox.Text && USER.Id != selectedUser.Id && !USER.IsTerminated) select USER;

            ///This call will actually connect to the RemoteDatabase and pull the data down.
            try
            {
                if (query.Count() == 0)
                {
                    usernameIsAvailable = true;
                }
            }
            catch (Exception ex)
            {
                Logging.LogException(ex);
            }
            return usernameIsAvailable;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override EntityObject GetSelectedEntityObject()
        {
            USER selected = comboBoxName.SelectedItem as USER;
            return selected;
        }

        /// <summary>
        /// 
        /// </summary>
        public override void MarkEntityDeleted()
        {
            try
            {
                USER user = comboBoxName.SelectedItem as USER;
                if (user.IsTraining != null && ((bool)user.IsTraining))
                {
                    UMD.ShowGuiMessageSTASafe_NOTHROW("You cannot delete the training mode user.");
                }
                else
                {
                    DominicaEntities.TerminateUser(user, Context);
                }
            }
            catch (Exception ex)
            {
                Logging.LogException(ex);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        public override void UpdateUsersEntitySource()
        {
            ///Create the query object.
            var query = from USER in Context.USERS
                        where (USER.IsTerminated == false & (USER.IsTraining == null || (((bool)USER.IsTraining == false))))
                        orderby USER.LastName, USER.FirstName
                        select USER;

            ObjectResult<USER> result = (ObjectResult<USER>)((ObjectQuery)query).Execute(MergeOption.AppendOnly);

            if (result != null)
            {
                List<USER> list = result.ToList();
                comboBoxName.ItemsSource = list;
                if (list != null && list.Count != 0)
                {
                    comboBoxName.SelectedItem = list.First();
                }
                else
                {
                    comboBoxName.ItemsSource = null;
                }
            }
            else
            {
                comboBoxName.ItemsSource = null;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override EntityObject AddNewEntityObject()
        {
            USER newUser = null;
            var q = from USER in Context.USERS
                    where USER.FirstName.Equals("Not Assigned") && USER.LastName.Equals("Not Assigned")
                    select USER;

            if (q.Count() == 0)
            {
                newUser = new USER();

                newUser.FirstName = "Not Assigned";
                newUser.LastName = "Not Assigned";
                newUser.UserName = "Not Assigned";
                newUser.ScreenName = "Not Assigned";
                newUser.Country = "USA";
                newUser.HiredDate = DateTime.Now;
                newUser.LoginKeyPassword = DominicaEntities.GenerateAvailableFohPassword();
                Context.USERS.AddObject(newUser);
            }
            else
            {
                newUser = q.First();

                if (newUser.IsTerminated)
                {
                    newUser.IsTerminated = false;
                }
            }

            return newUser;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override ComboBox GetEntityComboBox()
        {
            return comboBoxName;
        }

        /// <summary>
        /// Assure that the user has entered all of the required data.
        /// </summary>
        public override bool VerifyFormEntries()
        {
            ///Note that in this over-ride we return false only when we are not displaying a message.  Then we want the calling
            ///function to display the message by returning false.
            if (base.VerifyFormEntries())
            {
                ///Assure that if they want a FOH keypad login, they also fill in the keypad pword.
                if (tbtextboxKeypadPassword.Text.Count() < 4)
                {
                    UMD.ShowGuiMessageSTASafe_NOTHROW("Your keypad login code must be at least 4 numbers in length.");
                    return false;
                }
                USER selectedUser = comboBoxName.SelectedItem as USER;
                if (UsernameIsAvailable())
                {
                    try
                    {
                        if (!DominicaEntities.FohKeypadPasswordIsAvailable(selectedUser, tbtextboxKeypadPassword.Text, Context))
                        {
                            UMD.ShowGuiMessageSTASafe_NOTHROW("That general-user password is currently in use.");
                            return false;
                        }
                    }
                    catch (Exception e)
                    {
                        Logging.LogException(e);
                        return false;
                    }

                    if (selectedUser.LoginBohPassword != null)
                    {
                        string decryptPword = Sec.DecryptBytes(selectedUser.LoginBohPassword);
                        if (string.IsNullOrEmpty(_origBohPassword) || !_origBohPassword.Equals(decryptPword))
                        {

                            DominicaEntities.PasswordState state = DominicaEntities.VerifyBohPasswordValid(tbbohPasswordTextBox.Text, tbbohPasswordTextBox.Text, tbuserNameTextBox.Text);
                            if (state == DominicaEntities.PasswordState.AlphaNumericError)
                            {
                                UMD.ShowGuiMessageSTASafe_NOTHROW("The super-user password must contain both alphabetic and numeric characters.");
                                return false;
                            }
                            else if (state == DominicaEntities.PasswordState.SevenCharsError)
                            {
                                UMD.ShowGuiMessageSTASafe_NOTHROW("The super-user password must contain at least seven characters.");
                                return false;

                            }
                            else if (state == DominicaEntities.PasswordState.InUseError)
                            {
                                UMD.ShowGuiMessageSTASafe_NOTHROW("This password has been used as one of the last four passwords.");
                                return false;

                            }
                            else if (state == DominicaEntities.PasswordState.Accept)
                            {
                                selectedUser.BohPasswordDate = DateTime.Now;
                                Context.SaveChanges();
                            }
                        }
                    }
                }
                else
                {
                    UMD.ShowGuiMessageSTASafe_NOTHROW("A user with that name already exists.");
                    return false;
                }
            }
            return true;
        }
    }
}
